package com.studyweb.service.impl;

import com.studyweb.mapper.AchievementMapper;
import com.studyweb.mapper.UserAchievementMapper;
import com.studyweb.pojo.entity.Achievement;
import com.studyweb.pojo.entity.UserAchievement;
import com.studyweb.service.UserAchievementService;
import com.studyweb.service.UserPointsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户成就服务实现类
 * 
 * @author StudyWeb Team
 * @since 1.0.0
 */
@Slf4j
@Service
public class UserAchievementServiceImpl implements UserAchievementService {

    @Autowired
    private UserAchievementMapper userAchievementMapper;
    
    @Autowired
    private AchievementMapper achievementMapper;
    
    @Autowired
    private UserPointsService userPointsService;

    @Override
    public UserAchievement getById(Long id) {
        return userAchievementMapper.selectById(id);
    }

    @Override
    public List<UserAchievement> listByUserId(Long userId) {
        return userAchievementMapper.selectByUserId(userId);
    }

    @Override
    public List<UserAchievement> listByUserIdAndCategory(Long userId, String category) {
        return userAchievementMapper.selectByUserIdAndCategory(userId, category);
    }

    @Override
    public boolean hasAchievement(Long userId, Long achievementId) {
        UserAchievement userAchievement = userAchievementMapper.selectByUserIdAndAchievementId(userId, achievementId);
        return userAchievement != null;
    }

    @Override
    @Transactional
    public UserAchievement grantAchievement(Long userId, Long achievementId) {
        // 检查用户是否已获得该成就
        UserAchievement existingAchievement = userAchievementMapper.selectByUserIdAndAchievementId(userId, achievementId);
        if (existingAchievement != null) {
            log.info("用户已获得该成就: userId={}, achievementId={}", userId, achievementId);
            return existingAchievement;
        }
        
        // 获取成就信息
        Achievement achievement = achievementMapper.selectById(achievementId);
        if (achievement == null) {
            log.error("成就不存在: achievementId={}", achievementId);
            return null;
        }
        
        // 创建用户成就记录
        UserAchievement userAchievement = new UserAchievement();
        userAchievement.setUserId(userId);
        userAchievement.setAchievementId(achievementId);
        userAchievement.setEarnedDate(LocalDateTime.now());
        userAchievement.setIsDisplayed(true);
        userAchievement.setPointsClaimed(false); // 默认未领取积分
        
        // 保存用户成就记录
        userAchievementMapper.insert(userAchievement);
        
        // 设置成就信息
        userAchievement.setAchievement(achievement);
        
        // 成就主要提供荣誉徽章，积分需要用户手动领取
        log.info("用户获得新成就: userId={}, achievementName={}", userId, achievement.getName());
        
        return userAchievement;
    }
    
    @Override
    @Transactional
    public boolean claimAchievementPoints(Long userAchievementId, Long userId) {
        // 获取用户成就信息
        UserAchievement userAchievement = userAchievementMapper.selectById(userAchievementId);
        
        // 检查成就是否存在
        if (userAchievement == null) {
            log.error("用户成就不存在: userAchievementId={}", userAchievementId);
            return false;
        }
        
        // 检查是否是该用户的成就
        if (!userAchievement.getUserId().equals(userId)) {
            log.error("用户无权限领取该成就积分: userId={}, userAchievementId={}", userId, userAchievementId);
            return false;
        }
        
        // 检查积分是否已领取
        if (userAchievement.getPointsClaimed() != null && userAchievement.getPointsClaimed()) {
            log.info("成就积分已领取: userAchievementId={}", userAchievementId);
            return false;
        }
        
        // 获取成就信息
        Achievement achievement = achievementMapper.selectById(userAchievement.getAchievementId());
        if (achievement == null) {
            log.error("成就不存在: achievementId={}", userAchievement.getAchievementId());
            return false;
        }
        
        // 发放成就积分奖励
        if (achievement.getPointsReward() != null && achievement.getPointsReward() > 0) {
            userPointsService.addPoints(userId, achievement.getPointsReward());
            log.info("用户领取成就积分奖励: userId={}, points={}, achievementName={}", 
                    userId, achievement.getPointsReward(), achievement.getName());
        }
        
        // 更新成就状态为已领取
        userAchievement.setPointsClaimed(true);
        userAchievementMapper.update(userAchievement);
        
        return true;
    }

    @Override
    @Transactional
    public List<UserAchievement> checkAndGrantCheckinAchievements(Long userId, int consecutiveDays, int totalCheckins) {
        List<UserAchievement> newAchievements = new ArrayList<>();
        
        // 检查首次签到成就
        if (totalCheckins == 1) {
            List<Achievement> firstCheckinAchievements = achievementMapper.selectByConditionType("FIRST_CHECKIN");
            for (Achievement achievement : firstCheckinAchievements) {
                // 如果是第一次签到，且用户尚未获得该成就
                if (!hasAchievement(userId, achievement.getAchievementId())) {
                    UserAchievement userAchievement = grantAchievement(userId, achievement.getAchievementId());
                    if (userAchievement != null) {
                        newAchievements.add(userAchievement);
                    }
                }
            }
        }
        
        // 检查连续签到成就
        List<Achievement> consecutiveAchievements = achievementMapper.selectByConditionType("CONSECUTIVE_CHECKIN");
        for (Achievement achievement : consecutiveAchievements) {
            // 如果连续签到天数达到或超过成就条件值，且用户尚未获得该成就
            if (consecutiveDays >= achievement.getConditionValue() && !hasAchievement(userId, achievement.getAchievementId())) {
                UserAchievement userAchievement = grantAchievement(userId, achievement.getAchievementId());
                if (userAchievement != null) {
                    newAchievements.add(userAchievement);
                }
            }
        }
        
        // 检查累计签到成就
        List<Achievement> totalAchievements = achievementMapper.selectByConditionType("ACCUMULATED_CHECKIN");
        for (Achievement achievement : totalAchievements) {
            // 如果累计签到天数达到或超过成就条件值，且用户尚未获得该成就
            if (totalCheckins >= achievement.getConditionValue() && !hasAchievement(userId, achievement.getAchievementId())) {
                UserAchievement userAchievement = grantAchievement(userId, achievement.getAchievementId());
                if (userAchievement != null) {
                    newAchievements.add(userAchievement);
                }
            }
        }
        
        return newAchievements;
    }

    @Override
    public boolean updateDisplayStatus(Long id, boolean isDisplayed) {
        UserAchievement userAchievement = userAchievementMapper.selectById(id);
        if (userAchievement == null) {
            return false;
        }
        
        userAchievement.setIsDisplayed(isDisplayed);
        return userAchievementMapper.update(userAchievement) > 0;
    }

    @Override
    public boolean delete(Long id) {
        return userAchievementMapper.deleteById(id) > 0;
    }

    @Override
    public int countByUserId(Long userId) {
        return userAchievementMapper.countByUserId(userId);
    }

    @Override
    public int countByUserIdAndCategory(Long userId, String category) {
        return userAchievementMapper.countByUserIdAndCategory(userId, category);
    }
    
    @Override
    public int getUserPoints(Long userId) {
        com.studyweb.pojo.entity.UserPoints userPoints = userPointsService.getUserPoints(userId);
        return userPoints != null ? userPoints.getTotalPoints() : 0;
    }
}